package com.woniu.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniu.entity.PageData;
import com.woniu.entity.dto.FundFlowDTO;
import com.woniu.entity.vo.FundFlowVO;
import com.woniu.entity.vo.UserOrderNoPayDetailsVO;
import com.woniu.entity.vo.UserOrderPayDetailsVO;
import com.woniu.entity.vo.UserOrderVO;
import com.woniu.entity.dto.CreateOrderDTO;
import com.woniu.entity.dto.QueryOrderDTO;
import com.woniu.entity.vo.DetailOrderVO;
import com.woniu.entity.vo.ListOrderVO;
import com.woniu.mapper.OrderMapper;
import com.woniu.mapper.PatternMapper;
import com.woniu.pojo.Order;
import com.woniu.pojo.Pattern;
import com.woniu.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import com.woniu.utils.UserParkTimeUtils;
import com.woniu.utils.SMSUtils;
import com.woniu.utils.SpendUtils;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Calendar;


/**
* @author Ma.Lei
* @description 针对表【t_order】的数据库操作Service实现
* @createDate 2022-12-16 23:28:04
*/
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order>
    implements OrderService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private PatternMapper patternMapper;

    @Override
    public PageData queryFundFlow(Integer currentPage, Integer pageSize, FundFlowDTO fundFlowDTO) {
        IPage<FundFlowVO> page = new Page<>(currentPage, pageSize);
        IPage<FundFlowVO> fundFlowVOIPage = orderMapper.queryFundFlow(page, fundFlowDTO);
        return new PageData(fundFlowVOIPage.getTotal(),fundFlowVOIPage.getRecords());
    }

    @Override
    public List<UserOrderVO> listOrder(String id, String status) {
        List<UserOrderVO> orderVOList = orderMapper.listOrder(id,status);
        if (orderVOList !=null && orderVOList.size() > 0) {
            //计算订单在进行中的停车时长
            if ("1".equals(status)) {
                for (UserOrderVO userOrderVO : orderVOList) {
                    Date createTime = userOrderVO.getCreateTime();
                    String timeDiff = UserParkTimeUtils.timeDiff(createTime,new Date());
                    userOrderVO.setParkingTime(timeDiff);
                }
            }
            //待支付状态的停车时长
            if ("2".equals(status)){
                for (UserOrderVO userOrderVO : orderVOList) {
                    //根据订单编号获取订单
                    Order order = orderMapper.getByCode(userOrderVO.getOrderCode());
                    //订单创建时间
                    Date createTime = userOrderVO.getCreateTime();
                    //获取订单的创建时间和车辆离开时间
                    String timeDiff = UserParkTimeUtils.timeDiff(createTime,order.getLeaveTime());
                    userOrderVO.setParkingTime(timeDiff);
                    orderMapper.setOrderParkTime(userOrderVO.getOrderCode(),timeDiff);
                }
            }
            //已支付的停车时长
            if ("3".equals(status)){
                List<UserOrderVO> orderVOAppeal5 = orderMapper.listOrder(id,"5");
                List<UserOrderVO> orderVOAppeal6 = orderMapper.listOrder(id,"6");
                List<UserOrderVO> orderVOAppeal7 = orderMapper.listOrder(id,"7");
                orderVOList.addAll(orderVOAppeal5);
                orderVOList.addAll(orderVOAppeal6);
                orderVOList.addAll(orderVOAppeal7);
                //
                for (UserOrderVO userOrderVO : orderVOList) {
                    Order order = orderMapper.getByCode(userOrderVO.getOrderCode());
                    userOrderVO.setParkingTime(order.getParkingTime());
                }
            }
            //已完成的停车时长
            if ("4".equals(status)){
                for (UserOrderVO userOrderVO : orderVOList) {
                    Order order = orderMapper.getByCode(userOrderVO.getOrderCode());
                    userOrderVO.setParkingTime(order.getParkingTime());
                }
            }
        }
        return orderVOList;
    }

    /**
     * 查询进行中的订单
     * @param orderCode
     * @return
     */
    @Override
    public UserOrderVO orderOngoingDetails(String orderCode) {
        UserOrderVO userOrderVO = orderMapper.orderOngoingDetails(orderCode);
        Date createTime = userOrderVO.getCreateTime();
        String timeDiff = UserParkTimeUtils.timeDiff(createTime,new Date());
        userOrderVO.setParkingTime(timeDiff);
        return userOrderVO;
    }

    @Override
    public UserOrderNoPayDetailsVO orderNoPayOrFinishDetails(String orderCode) {
        UserOrderNoPayDetailsVO userOrderNoPayDetailsVO = orderMapper.orderNoPayOrFinishDetails(orderCode);
        return userOrderNoPayDetailsVO;
    }

    @Override
    public UserOrderPayDetailsVO orderPayDetails(String orderCode) {
        UserOrderPayDetailsVO userOrderPayDetailsVO = orderMapper.orderPayDetails(orderCode);
        return userOrderPayDetailsVO;
    }

    @Override
    public Order selectByOrderCode(String orderCode) {
        return orderMapper.selectByOrderCode(orderCode);
    }

    @Override
    public List<UserOrderVO> listOrderByCarNum(String id,String carNum) {
        return orderMapper.listOrderByCarNum(id,carNum);
    }

    @Override
    public List<Order>  checkCarNum(String carNum) {
        return orderMapper.checkCarNum(carNum);
    }


    @Override
    public Boolean createOrder(CreateOrderDTO createOrderDTO) {
        Order order = new Order();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        order.setOrderCode(sdf.format(new Date()) + SMSUtils.getRandomNum(6));
        order.setUserId(createOrderDTO.getUserId());
        order.setCarId(createOrderDTO.getCarId());
        order.setRoadId(createOrderDTO.getRoadId());
        order.setBerthId(createOrderDTO.getBerthId());
        order.setInspectorId(createOrderDTO.getInspectorId());
        order.setOrderStatus("1");
        order.setParkingTime("待驶离");
        return orderMapper.createOrder(order);
    }

    @Override
    public int updateOrderToPay(String id) {
        Order order = orderMapper.selectById(id);
        order.setLeaveTime(new Date());
        order.setParkingTime(SpendUtils.getParkingTime(order.getCreateTime(), order.getLeaveTime()));
        order.setOrderStatus("2");
        // 停车时间是否超过24小时
        long oneDay = 24 * 60 * 60 * 1000;
        if(oneDay >= order.getLeaveTime().getTime() - order.getCreateTime().getTime()){ // 不超过24小时
            // 开始停车的时间是否是工作日
            if("1".equals(SpendUtils.isWorkDay(order.getCreateTime()))){ // 是工作日
                // 开始停车的时间是否是繁忙时段
                LambdaQueryWrapper<Pattern> busyWrapper = new LambdaQueryWrapper<>();
                busyWrapper.eq(Pattern::getRoadId, order.getRoadId());
                busyWrapper.eq(Pattern::getIsWorkDay, "1");
                busyWrapper.eq(Pattern::getIsBusy, "1");
                Pattern busyPattern = patternMapper.selectOne(busyWrapper);
                LambdaQueryWrapper<Pattern> notBusyWrapper = new LambdaQueryWrapper<>();
                notBusyWrapper.eq(Pattern::getRoadId, order.getRoadId());
                notBusyWrapper.eq(Pattern::getIsWorkDay, "1");
                notBusyWrapper.eq(Pattern::getIsBusy, "0");
                Pattern notBusyPattern = patternMapper.selectOne(notBusyWrapper);
                if("1".equals(SpendUtils.isBusy(order.getCreateTime(),busyPattern.getTimeRangeStart(),busyPattern.getTimeRangeEnd()))){ // 是繁忙时段
                    inBusyTime(order, busyPattern);
                }else{ // 非繁忙时段
                    notBusyTime(order, notBusyPattern);
                }
            }else{ // 非工作日
                // 开始停车的时间是否是繁忙时段
                LambdaQueryWrapper<Pattern> busyWrapper = new LambdaQueryWrapper<>();
                busyWrapper.eq(Pattern::getRoadId, order.getRoadId());
                busyWrapper.eq(Pattern::getIsWorkDay, "0");
                busyWrapper.eq(Pattern::getIsBusy, "1");
                Pattern busyPattern = patternMapper.selectOne(busyWrapper);
                LambdaQueryWrapper<Pattern> notBusyWrapper = new LambdaQueryWrapper<>();
                notBusyWrapper.eq(Pattern::getRoadId, order.getRoadId());
                notBusyWrapper.eq(Pattern::getIsWorkDay, "0");
                notBusyWrapper.eq(Pattern::getIsBusy, "0");
                Pattern notBusyPattern = patternMapper.selectOne(notBusyWrapper);
                if("1".equals(SpendUtils.isBusy(order.getCreateTime(),busyPattern.getTimeRangeStart(),busyPattern.getTimeRangeEnd()))){ // 是繁忙时段
                    inBusyTime(order, busyPattern);
                }else{ // 非繁忙时段
                    notBusyTime(order, notBusyPattern);
                }
            }
        }else{ // 超过24小时
            Calendar startCalendar = Calendar.getInstance();
            startCalendar.setTime(order.getCreateTime());
            Calendar endCalendar = Calendar.getInstance();
            endCalendar.setTime(order.getLeaveTime());
            int day = endCalendar.get(Calendar.DAY_OF_YEAR) - startCalendar.get(Calendar.DAY_OF_YEAR);
            int hour = endCalendar.get(Calendar.HOUR_OF_DAY) - startCalendar.get(Calendar.HOUR_OF_DAY);
            BigDecimal price = BigDecimal.valueOf(day).multiply(BigDecimal.valueOf(100)).add(BigDecimal.valueOf(hour).multiply(BigDecimal.valueOf(5)));
            order.setPrice(price);
        }
        return orderMapper.updateById(order);
    }

    private void notBusyTime(Order order, Pattern notBusyPattern) {
        Integer standard = Integer.valueOf(notBusyPattern.getStandard());
        Calendar startCalendar = Calendar.getInstance();
        startCalendar.setTime(order.getCreateTime());
        Calendar endCalendar = Calendar.getInstance();
        endCalendar.setTime(order.getLeaveTime());
        int day = endCalendar.get(Calendar.DAY_OF_YEAR) - startCalendar.get(Calendar.DAY_OF_YEAR);
        int hour = endCalendar.get(Calendar.HOUR_OF_DAY) - startCalendar.get(Calendar.HOUR_OF_DAY);
        int minute = endCalendar.get(Calendar.MINUTE) - startCalendar.get(Calendar.MINUTE);
        int second = endCalendar.get(Calendar.SECOND) - startCalendar.get(Calendar.SECOND);
        if(hour < 0){
            hour = hour + 24 * day;
        }
        if(minute < 0){
            minute = minute + 60;
            hour--;
        }
        if(second < 0){
            minute--;
        }
        if(second >= 30){
            minute++;
        }
        Integer freeTime = Integer.valueOf(notBusyPattern.getFreeTime());
        String maxMoney = notBusyPattern.getMaxMoney();
        if(hour ==0 && minute <= freeTime){ // 停车时间是否在免费时间内
            order.setPrice(new BigDecimal(0));
        }else{ // 不在免费时间内
            int allMinute = hour * 60 + minute;
            if("1".equals(notBusyPattern.getIsInclude())){ // 计费包含免费时长
                BigDecimal price = BigDecimal.valueOf(standard).multiply(BigDecimal.valueOf(hour).add(BigDecimal.valueOf(minute).divide(BigDecimal.valueOf(60),2, BigDecimal.ROUND_HALF_UP)));
                if(maxMoney != null){
                    if(price.compareTo(BigDecimal.valueOf(Integer.valueOf(maxMoney))) == 1){
                        order.setPrice(new BigDecimal(maxMoney));
                    }else{
                        order.setPrice(price);
                    }
                }else{
                    order.setPrice(price);
                }
            }else{ // 不包含免费时长
                BigDecimal money = BigDecimal.valueOf(standard).multiply(BigDecimal.valueOf(allMinute).subtract(BigDecimal.valueOf(freeTime))).divide(BigDecimal.valueOf(60),2, BigDecimal.ROUND_HALF_UP);
                if(maxMoney != null){
                    if(money.compareTo(BigDecimal.valueOf(Integer.valueOf(maxMoney))) == 1){
                        order.setPrice(new BigDecimal(maxMoney));
                    }else{
                        order.setPrice(money);
                    }
                }else{
                    order.setPrice(money);
                }
            }
        }
    }

    private void inBusyTime(Order order, Pattern busyPattern) {
        Integer standard = Integer.valueOf(busyPattern.getStandard());
        Calendar startCalendar = Calendar.getInstance();
        startCalendar.setTime(order.getCreateTime());
        Calendar endCalendar = Calendar.getInstance();
        endCalendar.setTime(order.getLeaveTime());
        int day = endCalendar.get(Calendar.DAY_OF_YEAR) - startCalendar.get(Calendar.DAY_OF_YEAR);
        int hour = endCalendar.get(Calendar.HOUR_OF_DAY) - startCalendar.get(Calendar.HOUR_OF_DAY);
        int minute = endCalendar.get(Calendar.MINUTE) - startCalendar.get(Calendar.MINUTE);
        int second = endCalendar.get(Calendar.SECOND) - startCalendar.get(Calendar.SECOND);
        if(hour < 0){
            hour = hour + 24 * day;
        }
        if(minute < 0){
            minute = minute + 60;
            hour--;
        }
        if(second < 0){
            minute--;
        }
        if(second >= 30){
            minute++;
        }
        Integer freeTime = Integer.valueOf(busyPattern.getFreeTime());
        String maxMoney = busyPattern.getMaxMoney();
        if(hour ==0 && minute <= freeTime){ // 停车时间是否在免费时间内
            order.setPrice(new BigDecimal(0));
        }else{ // 不在免费时间内
            int allMinute = hour * 60 + minute;
            if("1".equals(busyPattern.getIsInclude())){ // 计费包含免费时长
                BigDecimal price = BigDecimal.valueOf(standard).multiply(BigDecimal.valueOf(hour).add(BigDecimal.valueOf(minute).divide(BigDecimal.valueOf(60),2, BigDecimal.ROUND_HALF_UP)));
                if(maxMoney != null){
                    if(price.compareTo(BigDecimal.valueOf(Integer.valueOf(maxMoney))) == 1){
                        order.setPrice(new BigDecimal(maxMoney));
                    }else{
                        order.setPrice(price);
                    }
                }else{
                    order.setPrice(price);
                }
            }else{ // 不包含免费时长
                BigDecimal money = BigDecimal.valueOf(standard).multiply(BigDecimal.valueOf(allMinute).subtract(BigDecimal.valueOf(freeTime))).divide(BigDecimal.valueOf(60),2, BigDecimal.ROUND_HALF_UP);
                if(maxMoney != null){
                    if(money.compareTo(BigDecimal.valueOf(Integer.valueOf(maxMoney))) == 1){
                        order.setPrice(new BigDecimal(maxMoney));
                    }else{
                        order.setPrice(money);
                    }
                }else{
                    order.setPrice(money);
                }
            }
        }
    }

    @Override
    public PageData listSearch(Integer currentPage, Integer pageSize, QueryOrderDTO queryOrderDTO) {
        // 1.创建分页对象
        IPage<ListOrderVO> page = new Page<>(currentPage,pageSize);
        // 2.查询数据
        IPage<ListOrderVO> orderPage = orderMapper.listSearch(page,queryOrderDTO);
        // 3.封装分页数据
        PageData pageData = new PageData(orderPage.getTotal(), orderPage.getRecords());
        return pageData;
    }

    @Override
    public List<ListOrderVO> exportByDTO(QueryOrderDTO queryOrderDTO) {
        List<ListOrderVO> orderVOList = orderMapper.exportByDTO(queryOrderDTO);
        for (ListOrderVO orderVO : orderVOList) {
            if(queryOrderDTO.getIsException()){ // 是异常订单
                switch (orderVO.getOrderStatus()){
                    case "5":
                        orderVO.setOrderStatus("待处理");
                        break;
                    case "6":
                        orderVO.setOrderStatus("不通过");
                        break;
                    case "7":
                        orderVO.setOrderStatus("已通过");
                        break;
                    default:
                        orderVO.setOrderStatus("未获取到状态");
                        break;
                }
            }
            if(!queryOrderDTO.getIsException()){ //  不是异常订单
                switch (orderVO.getOrderStatus()){
                    case "1":
                        orderVO.setOrderStatus("进行中");
                        break;
                    case "2":
                        orderVO.setOrderStatus("待支付");
                        break;
                    case "3":
                        orderVO.setOrderStatus("已支付");
                        break;
                    case "4":
                        orderVO.setOrderStatus("已完成");
                        break;
                    case "5":
                        orderVO.setOrderStatus("申诉中");
                        break;
                    case "6":
                        orderVO.setOrderStatus("申诉失败");
                        break;
                    case "7":
                        orderVO.setOrderStatus("已退款");
                        break;
                    default:
                        orderVO.setOrderStatus("未获取到状态");
                        break;
                }
            }
            if(orderVO.getPrice() == null){
                orderVO.setPrice("待核算");
            }
        }
        return orderVOList;
    }

    @Override
    public DetailOrderVO getDetailById(String id) {
        return orderMapper.getDetailById(id);
    }

    @Override
    public Order getByOrderCode(String out_trade_no) {
        return orderMapper.getByOrderCode(out_trade_no);
    }
}




